package com.linkedlist;

import java.nio.channels.Pipe;

public class Josepfu {
    public static void main(String[] args) {
        //测试
        CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
        circleSingleLinkedList.addBoy(5);
        circleSingleLinkedList.showBoy();
        //测试出圈
        circleSingleLinkedList.countBoy(1,2,5);
    }
}

//创建环形单项链表
class CircleSingleLinkedList{
    //创建一个first节点，当前没有编号
    private Boy first = null;
    //添加小孩节点
    public void addBoy(int nums){
        //对nums做一个数据校验
        if (nums < 1){
            System.out.println("nums的值不正确");
            return;
        }
        Boy curBoy = null;
        //使用for循环创建环形链表
        for (int i = 1; i <= nums; i++) {
            //根据编号,创建节点
            Boy boy = new Boy(i);
            //如果是第一个小孩
            if (i == 1){
                first = boy;
                first.setNext(first);//构成环状
                curBoy = first;
            }
            else {
                curBoy.setNext(boy);
                boy.setNext(first);
                curBoy = boy;
            }
        }
    }

    //遍历当前环形链表
    public void showBoy(){
        //判断链表是否
        if (first == null){
            System.out.println("链表为空");
            return;
        }
        Boy curBoy = first;
        while (true){
            System.out.printf("小孩的编号为：" + curBoy.getNo());
            System.out.println();
            if (curBoy.getNext() == first){
                break;
            }
            else {
                curBoy = curBoy.getNext();
            }
        }
    }

    //根据用户的输入，计算出小孩出圈的顺序
    //startNo表示从第几个小孩开始数数，countNum表示数几下，nums表示最初有几个小孩在圈中
    public void countBoy(int startNo,int countNum,int nums){
        //先对数据进行校验
        if (first == null || startNo < 1 || startNo > nums){
            System.out.println("参数输入有误");
            return;
        }

        //先把first指向第一个报数的小孩
        for (int j = 0;j < startNo - 1;j++){
            first = first.getNext();
        }

        //创建辅助指针，指向最后一个节点
        Boy helper =first;
        while (true){
            if (helper.getNext() == first){
                break;
            }
            else {
                helper = helper.getNext();
            }
        }
        while (true){
            if (helper == first){//说明圈中只有一个节点
                break;
            }
            else {
                for (int j = 0;j < countNum - 1;j++){
                    first = first.getNext();
                    helper = helper.getNext();
                }
                System.out.println("小孩" + first.getNo() + "出圈");
                first = first.getNext();
                helper.setNext(first);
            }
        }
        System.out.println("最后留在圈中的小孩编号为：" + first.getNo());
    }
}

//创建一个Boy类,表示一个节点
class Boy{
    private int no;//编号
    private Boy next;//指向下一个节点
    public Boy(int no){
        this.no = no;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public Boy getNext() {
        return next;
    }

    public void setNext(Boy next) {
        this.next = next;
    }
}